﻿using System;
using System.Diagnostics;
using System.IO;
using System.Management;
using System.Text;
using System.Runtime.InteropServices;  

namespace Tzx.TUpdater.Utilities
{
    /// <summary>
    /// 文件辅助,进程辅助,
    /// </summary>
    internal class FileHelper
    {
        /// <summary>
        /// 创建目录
        /// </summary>
        /// <param name="path"></param>
        public static bool CreateDirtory(string path)
        {
            if (!File.Exists(path))
            {
                string[] dirArray = path.Split('\\');
                string temp = string.Empty;
                for (int i = 0; i < dirArray.Length - 1; i++)
                {
                    temp += dirArray[i].Trim() + "\\";
                    if (!Directory.Exists(temp))
                    {
                        DirectoryInfo dif = Directory.CreateDirectory(temp);
                    }
                }
                return true;
            }
            return false;
        }

        /*
         * 调用 
         * cmd.exe /C choice /t 1 /d y /n > nul & del 自身exe & rename 更新的exe 自身exe
         * 来更新自身exe
         */

        /// <summary>
        /// 删除文件
        /// <remarks>
        /// <![CDATA[
        /// 调用:
        /// cmd.exe /C choice /t 1 /d y /n > nul & del 自身exe & rename 更新的exe 自身exe
        /// 来更新自身exe
        /// ]]>
        /// </remarks>
        /// </summary>
        public static bool DeleteFile(string filePathName)
        {
            if (!File.Exists(filePathName))
            {
                return false;
            }

            File.Delete(filePathName);
            return true;
        }

        /// <summary>
        /// 杀死进程及其下面的线程
        /// </summary>
        /// <param name="allProcess"></param>
        /// <param name="exeName"></param>
        /// <returns></returns>
        public static bool KillExeProcess(Process[] allProcess, string exeName)
        {
            //
            if (allProcess == null || allProcess.Length == 0)
            {
                return false;
            }
            exeName = string.Format("{0}", exeName);
            if (exeName.Length == 0)
            {
                return false;
            }

            //
            foreach (Process p in allProcess)
            {
                string runingExe = string.Format("{0}.exe", p.ProcessName);
                if (String.Compare(runingExe, exeName, StringComparison.InvariantCultureIgnoreCase)==0)
                {
                    //进程名称相同
                    for (int i = 0; i < p.Threads.Count; i++)
                    {
                        //结束所有线程
                        p.Threads[i].Dispose();
                    }
                    p.Kill();
                    //isRun = true;
                    //break;
                }
            } //foreach
            return true;
        }

        /// <summary>
        /// 用regsvr32注册ActiveDll
        /// </summary>
        /// <param name="dllFilePathName"></param>
        public static bool Regsvr32Dll(string dllFilePathName)
        {
            //
            dllFilePathName = string.Format("{0}", dllFilePathName).Trim(' ', '"');
            if (dllFilePathName.Length == 0)
            {
                return false;
            }
            dllFilePathName = string.Format("\"{0}\"", dllFilePathName);//路径中不能有空格,若有就用双引号,包起来

            //
            const string regsvr32 = "regsvr32.exe";
            Process p = new Process();
            p.StartInfo.FileName = regsvr32;
            p.StartInfo.Arguments = string.Format("/s {0}", dllFilePathName); //参数与路径间有一个空格
            //p.StartInfo.Arguments = string.Format(" {0}", dllFilePathName); //参数与路径间有一个空格
            p.Start(); //用regsvr32注册ActiveDll

            //
            return true;
        }

        /// <summary>
        /// 用 RegAsm.exe 注册 .Net Dll
        /// </summary>
        /// <param name="dotnetDllFilePathName"></param>
        /// <returns></returns>
        [Obsolete("暂未完全实现",true)]
        private static bool RegasmDll(string dotnetDllFilePathName)
        {
            //
            dotnetDllFilePathName = string.Format("{0}", dotnetDllFilePathName).Trim(' ', '"');
            if (dotnetDllFilePathName.Length == 0)
            {
                return false;
            }
            dotnetDllFilePathName = string.Format("\"{0}\"", dotnetDllFilePathName);//路径中不能有空格,若有就用双引号,包起来

            //是否64位系统
            int osBit = GetOSBit();
            bool isDot4 = false;

            //路径,%windir%\Microsoft.NET\

            //.net 2.0/3.0/3.5:
            //C:\Windows\Microsoft.NET\Framework  \V2.0.50727\RegAsm.exe
            //C:\Windows\Microsoft.NET\Framework64\V2.0.50727\RegAsm.exe

            //.net 4.0:(32位Framework框架 / 64位Framework框架)
            //C:\Windows\Microsoft.NET\Framework  \v4.0.30319\RegAsm.exe
            //C:\Windows\Microsoft.NET\Framework64\v4.0.30319\RegAsm.exe

            string path = string.Format("%windir%\\Microsoft.NET\\{0}\\{1}\\",
                osBit == 64 ? "Framework64" : "Framework",
                isDot4 ? "v4.0.30319" : "V2.0.50727"
                );

            //命令程序
            const string exe = "RegAsm.exe";
            string regasm = string.Format("{0}\\{1}", path.TrimEnd('\\','/'), exe);
            Process p = new Process();
            p.StartInfo.FileName = regasm;
            p.StartInfo.Arguments = string.Format(" {0} /silent ", dotnetDllFilePathName); //参数与路径间有一个空格
            //p.StartInfo.Arguments = string.Format(" {0} ", dllFilePathName); //参数与路径间有一个空格
            p.Start();

            //
            return true;
        }

        /// <summary>
        /// 当前操作系统是32位还是64位
        /// </summary>
        /// <returns></returns>
        private static int GetOSBit()
        {
            //这里需要引用System.Management
            //该方法在以Guest用户登录的情况下抛出异常
            try
            {
                string addressWidth = String.Empty;
                ConnectionOptions mConnOption = new ConnectionOptions();
                ManagementScope mMs = new ManagementScope(@"\\localhost", mConnOption);
                ObjectQuery mQuery = new ObjectQuery("select AddressWidth from Win32_Processor");
                ManagementObjectSearcher mSearcher = new ManagementObjectSearcher(mMs, mQuery);
                ManagementObjectCollection mObjectCollection = mSearcher.Get();
                foreach (ManagementObject mObject in mObjectCollection)
                {
                    addressWidth = mObject["AddressWidth"].ToString();
                }
                return Int32.Parse(addressWidth);
            }
            catch (Exception)
            {
                return 32;
            }
        }

        #region 文件是否被占用

        //参考: http://blog.csdn.net/lanpy88/article/details/7305184

        [DllImport("kernel32.dll")]
        public static extern IntPtr _lopen(string lpPathName, int iReadWrite);

        [DllImport("kernel32.dll")]
        public static extern bool CloseHandle(IntPtr hObject);

        public const int OF_READWRITE = 2;
        public const int OF_SHARE_DENY_NONE = 0x40;
        public static readonly IntPtr HFILE_ERROR = new IntPtr(-1);

        /// <summary>
        /// 文件是否已被占用(API)
        /// </summary>
        /// <param name="vFileName"></param>
        /// <returns></returns>
        public static bool IsFileInUse(string vFileName)
        {
            if (!File.Exists(vFileName))
            {
                return false;//("文件都不存在!"); 
            }

            IntPtr vHandle = _lopen(vFileName, OF_READWRITE | OF_SHARE_DENY_NONE);
            if (vHandle == HFILE_ERROR)
            {
                return true;//("文件被占用！");
            }

            CloseHandle(vHandle);
            return false;//("没有被占用！");  
        }

        #endregion

    }
}